#include <iostream>
#include <thread>
#include <coroutine>
#include <chrono>
using namespace std;
// 1、c++函数中出现了co_await、co_yield、co_return: 这个函数就变成了协程
// 2、co_await 让协程停一下、等条件满足再执行，具体怎么停需要实现一个协议Awaitable
// 3、Awaitable 要求实现一下三个函数
//      1、await_ready() 告诉编译器现在能不能直接拿到结果
//              1、await_ready返回true表示不用暂停、返回false 需要暂停
//      2、await_suspend() 定义如何暂停
//              1、await_suspend的参数： std::coroutine_handle<>,用它在未来唤醒协程
//              2、调用handle.resume恢复执行
//              3、返回类型是void或者bool
//      3、await_resume() 定义如何恢复
//              1、当协程恢复(或者压根没暂停)时，这个函数被调用返回值就是co_await的结果
// 4、C++ 协程有特定的返回类型要求
//      1、它必须包含一个名为 promise_type 的内嵌类型： 控制协程行为、或者与调用者交换数据、
//      2、promise_type 要求 return_void 和 return_value只能二选一实现

class IntReader
{
public:
    bool await_ready()
    {
        return false;
    }
    void await_suspend(coroutine_handle<void> handle)
    {
        thread t1([=]()
                  {
            this_thread::sleep_for(chrono::seconds(1));
            handle.resume(); });

        t1.detach();
    }
    int await_resume()
    {
        return 1;
    }
};
class Task
{
public:
    class promise_type
    {
    public:
        Task get_return_object() { return {}; }
        suspend_never initial_suspend() { return {}; }
        suspend_never final_suspend() noexcept { return {}; }
        void return_void() {}
        void unhandled_exception() { exit(1); }
    };
};
Task prinft_inf()
{
    IntReader r1;
    int res = co_await r1;
    cout << "res is " << res << endl;
    IntReader r2;
    res += co_await r2;
    cout << "res is " << res << endl;
}
int main()
{
    prinft_inf();
    this_thread::sleep_for(chrono::seconds(3));
    cout << "main thread is finish" << endl;
    return 0;
}